
#pragma once

#include <list>
#include <map>
using std::multimap;
using std::pair;
using std::list;

#include "CEvent.h"
#include "IListener.h"

class DHD_EventSystem
{
	private:

		multimap<EVENTID, IListener*>	m_ClientDatabase;
	
		list<CEvent>		m_CurrentEvents;

		void DispatchEvent(CEvent* pEvent);
		bool AlreadyRegistered(EVENTID eventID, IListener* pClient);

		DHD_EventSystem() {}
		DHD_EventSystem(const DHD_EventSystem&);
		DHD_EventSystem& operator=(const DHD_EventSystem&);

		~DHD_EventSystem() {}

	public:

		static DHD_EventSystem* GetInstance(void)
		{
			static DHD_EventSystem instance;
			return &instance;
		}

		//	This adds a client to the database.  This will make new "buckets" if necessary and then
		//	add the client to that given bucket.
		void RegisterClient(EVENTID eventID, IListener* pClient);

		//	Unregisters the client for the specified event only
		void UnregisterClient(EVENTID eventID, IListener* pClient);

		//	Removes the client from the database entirely
		void UnregisterClientAll(IListener* pClient);

		//	Sends an event to be processed later on.
		void SendEvent(EVENTID eventID, void* pData = NULL);

		//	Processes all events in our event list.
		void ProcessEvents(void);

		//	Clears all pending events
		void ClearEvents(void);

		//	Unregisters all objects
		void ShutdownEventSystem(void);
};